package com.zjcloud.academic.service.impl;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.zjcloud.academic.mapper.AcScheduleTaskMapper;
import com.zjcloud.academic.domain.AcScheduleTask;
import com.zjcloud.academic.domain.AcCourseSchedule;
import com.zjcloud.academic.service.IAcScheduleTaskService;
import com.zjcloud.academic.service.IntelligentScheduleService;
import com.zjcloud.common.core.text.Convert;
import com.zjcloud.common.utils.DateUtils;

/**
 * 排课任务Service业务层处理
 * 
 * @author zjcloud
 * @date 2024-12-19
 */
@Service
public class AcScheduleTaskServiceImpl implements IAcScheduleTaskService 
{
    private static final Logger log = LoggerFactory.getLogger(AcScheduleTaskServiceImpl.class);
    
    @Autowired
    @Qualifier("academicAcScheduleTaskMapper")
    private AcScheduleTaskMapper acScheduleTaskMapper;
    
    @Autowired
    private IntelligentScheduleService intelligentScheduleService;

    /**
     * 查询排课任务
     * 
     * @param id 排课任务主键
     * @return 排课任务
     */
    @Override
    public AcScheduleTask selectAcScheduleTaskById(Long id)
    {
        return acScheduleTaskMapper.selectAcScheduleTaskById(id);
    }

    /**
     * 查询排课任务列表
     * 
     * @param acScheduleTask 排课任务
     * @return 排课任务
     */
    @Override
    public List<AcScheduleTask> selectAcScheduleTaskList(AcScheduleTask acScheduleTask)
    {
        return acScheduleTaskMapper.selectAcScheduleTaskList(acScheduleTask);
    }

    /**
     * 根据学期ID查询排课任务列表
     * 
     * @param semesterId 学期ID
     * @return 排课任务集合
     */
    @Override
    public List<AcScheduleTask> selectAcScheduleTaskBySemesterId(Long semesterId)
    {
        return acScheduleTaskMapper.selectAcScheduleTaskBySemesterId(semesterId);
    }

    /**
     * 新增排课任务
     * 
     * @param acScheduleTask 排课任务
     * @return 结果
     */
    @Override
    public int insertAcScheduleTask(AcScheduleTask acScheduleTask)
    {
        return acScheduleTaskMapper.insertAcScheduleTask(acScheduleTask);
    }

    /**
     * 修改排课任务
     * 
     * @param acScheduleTask 排课任务
     * @return 结果
     */
    @Override
    public int updateAcScheduleTask(AcScheduleTask acScheduleTask)
    {
        return acScheduleTaskMapper.updateAcScheduleTask(acScheduleTask);
    }

    /**
     * 删除排课任务对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteAcScheduleTaskByIds(Long[] ids)
    {
        return acScheduleTaskMapper.deleteAcScheduleTaskByIds(ids);
    }

    /**
     * 删除排课任务信息
     * 
     * @param id 排课任务主键
     * @return 结果
     */
    @Override
    public int deleteAcScheduleTaskById(Long id)
    {
        return acScheduleTaskMapper.deleteAcScheduleTaskById(id);
    }

    /**
     * 更新任务状态
     * 
     * @param id 任务ID
     * @param status 状态
     * @return 结果
     */
    @Override
    public int updateTaskStatus(Long id, String status)
    {
        return acScheduleTaskMapper.updateTaskStatus(id, status);
    }

    /**
     * 更新任务进度
     * 
     * @param id 任务ID
     * @param progress 进度值
     * @return 结果
     */
    @Override
    public int updateTaskProgress(Long id, Integer progress)
    {
        return acScheduleTaskMapper.updateTaskProgress(id, progress);
    }

    /**
     * 开始任务
     * 
     * @param id 任务ID
     * @return 结果
     */
    @Override
    public int startTask(Long id)
    {
        int result = acScheduleTaskMapper.updateTaskStatus(id, "running");
        if (result > 0) {
            // 异步执行排课任务
            executeScheduleTaskAsync(id);
        }
        return result;
    }

    /**
     * 异步执行排课任务
     * @param taskId 任务ID
     */
    @Async
    public void executeScheduleTaskAsync(Long taskId) {
        try {
            AcScheduleTask task = selectAcScheduleTaskById(taskId);
            if (task == null) {
                log.error("排课任务不存在，任务ID: {}", taskId);
                return;
            }
            
            log.info("开始执行排课任务，任务ID: {}，任务名称: {}", taskId, task.getTaskName());
            
            // 更新任务开始时间
            acScheduleTaskMapper.updateTaskStartTime(taskId, DateUtils.getNowDate());
            
            // 设置初始进度
            updateTaskProgress(taskId, 0);
            
            // 执行智能排课
            intelligentScheduleService.intelligentSchedule(task.getSemesterId(), new IntelligentScheduleService.ProgressCallback() {
                @Override
                public void onProgressUpdate(int progress, String message) {
                    updateTaskProgress(taskId, progress);
                    log.info("排课任务 {} 进度: {}", taskId, message);
                }
                
                @Override
                public void onComplete(List<AcCourseSchedule> result) {
                    log.info("排课任务 {} 完成，生成 {} 条课程安排", taskId, result.size());
                }
                
                @Override
                public void onError(String error) {
                    log.error("排课任务 {} 失败: {}", taskId, error);
                    // 更新任务状态为失败
                    acScheduleTaskMapper.updateTaskStatus(taskId, "failed");
                    // 记录错误信息
                    AcScheduleTask task = new AcScheduleTask();
                    task.setId(taskId);
                    task.setErrorMessage(error);
                    acScheduleTaskMapper.updateAcScheduleTask(task);
                }
            });
            
            // 任务完成
            completeTask(taskId);
            log.info("排课任务执行完成，任务ID: {}", taskId);
            
        } catch (Exception e) {
            log.error("排课任务执行失败，任务ID: {}", taskId, e);
            // 更新任务状态为失败
            acScheduleTaskMapper.updateTaskStatus(taskId, "failed");
            // 记录错误信息
            AcScheduleTask task = new AcScheduleTask();
            task.setId(taskId);
            task.setErrorMessage(e.getMessage());
            acScheduleTaskMapper.updateAcScheduleTask(task);
        }
    }

    /**
     * 完成任务
     * 
     * @param id 任务ID
     * @return 结果
     */
    @Override
    public int completeTask(Long id)
    {
        int result = acScheduleTaskMapper.updateTaskStatus(id, "completed");
        if (result > 0) {
            // 更新任务结束时间
            acScheduleTaskMapper.updateTaskEndTime(id, DateUtils.getNowDate());
        }
        return result;
    }
}